package com.mentorgen.tools.profile.output;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.mentorgen.tools.profile.Controller;
import com.mentorgen.tools.profile.runtime.Method;

public class ProfileClassDotDump  extends ProfileDotDump implements IFProfileDotDump  {

	public void writeEdges(PrintWriter fileWriter, Map<String, Method> methodDic) {
		Set<String> classNameSet = new HashSet<String>();
		for (Method method : methodDic.values())
			if (method.getClassName() != null)
				classNameSet.add(method.getClassName());
			else 
				classNameSet.add(ProfileDotDump.DEFUALT_BNAME);
		
		writeDotNodes(fileWriter, classNameSet);
	}

	public void writeNodes(PrintWriter fileWriter, Map<String, Method> methodDic) {
		for (String methodKey : methodDic.keySet())
			calculateEdges(methodDic.get(methodKey));
		writeDotEdges(fileWriter);
	}
	
	private void calculateEdges(Method method){
		
		if (method.getOutMap().keySet().size() == 0)
			return;
		
		if (Controller._debug)
			logWriter.println(">> " + method.getBundleName() + ":" + method.toString());
		
		for (String methodKey : method.getOutMap().keySet()){
			Method inMethod = method.getOutMap().get(methodKey);
			String outClass = (method.getClassName() != null) ? method.getClassName() : ProfileDotDump.DEFUALT_BNAME;
			String inClass  = (inMethod.getClassName() != null) ? inMethod.getClassName() : ProfileDotDump.DEFUALT_BNAME;
			
			//	The line below makes sure that no two methods with the same 
			//	class loader are accounted as adding data to an edge. 
			if (method.getLoaderID().equals(inMethod.getLoaderID()))
				continue;
			
			String key = normalizeName(outClass)+"___"+normalizeName(inClass);
			Long data = dataMap.get(key);
			Long count = countMap.get(key);
			if (data == null){
				data = method.getAvgOutDataForMethod(methodKey);
				count = method.getOutCountForMethod(methodKey);
			}
			else {
				data += method.getAvgOutDataForMethod(methodKey);
				count += method.getOutCountForMethod(methodKey);
			}
			
			dataMap.put(key, data);
			countMap.put(key, count);
			
			if (Controller._debug)
				logWriter.println("\tFROM:" +  method.getClassName() + "- TO:" + inClass + 
						" (" + method.toString() + ">" + inMethod.toString() + ") == (" + 
						method.getAvgOutDataForMethod(methodKey) + "_" + 
						method.getOutCountForMethod(methodKey) + ")");
		}
		if (Controller._debug)
			logWriter.println(" --- ");
		
	}

	public void dumpGraph(String sourceFile, String targetFile) throws IOException {
		try {
			Process pr = Runtime.getRuntime().exec("fdp -Tpng -o" + targetFile + " " + sourceFile);
			pr.waitFor();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			System.out.println("Done Drawing the Class Graph.");
		}
	}

}
